﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace WpfApp1.Controls;

public class BusyMessageBox : Window
{
    public BusyMessageBox()
    {
        BuildContent();

        Closing += BusyMessageBox_Closing;
        abortButton.Click += AbortButton_Click;

        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += Timer_Tick;
    }

    private readonly DispatcherTimer timer = new();
    private readonly Button okButton = new() { Content = "Ok" };
    private readonly Button abortButton = new() { Content = "Abort" };

    private CancellationTokenSource? cancellationTokenSource;
    private int countdownSeconds;

    private void BuildContent()
    {
        FontSize = 16;
        Height = 240;
        Width = 320;
        Title = "我是标题";

        var child = new StackPanel();

        child.Children.Add(new TextBlock { Text = "主内容" });

        var bottomPanel = new WrapPanel();
        bottomPanel.Children.Add(okButton);
        bottomPanel.Children.Add(abortButton);
        child.Children.Add(bottomPanel);

        Content = child;
    }

    private void UpdateOkLabel(int countdownSeconds)
    {
        okButton.Content = $"Ok({countdownSeconds})";
    }

    private void BusyMessageBox_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
    {
        timer.Stop();
    }

    private void Timer_Tick(object? sender, EventArgs e)
    {
        countdownSeconds -= 1;
        if (countdownSeconds > 0)
        {
            UpdateOkLabel(countdownSeconds);
        }
        else
        {
            cancellationTokenSource?.Cancel();
        }
    }

    private void AbortButton_Click(object sender, RoutedEventArgs e)
    {
        cancellationTokenSource?.Cancel();
    }

    public void Show(CancellationToken token, int countdownSeconds = 0)
    {
        cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        cancellationToken.Register(() =>
        {
            Dispatcher.Invoke(() =>
            {
                if (IsLoaded)
                {
                    Close();
                }
            });
        });

        if (countdownSeconds > 0)
        {
            this.countdownSeconds = countdownSeconds;
            UpdateOkLabel(countdownSeconds);
            timer.Start();
        }

        Show();
    }
}